package com.fanly.weixin.controller;

import cn.hutool.crypto.digest.DigestUtil;
import com.fanly.weixin.entity.Message;
import com.fanly.weixin.entity.MessageType;
import com.fanly.weixin.utils.JokeUtils;
import com.fanly.weixin.utils.MessageUtils;
import com.fanly.weixin.utils.PostCodeUtils;
import com.fanly.weixin.utils.WeatherUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author D-BJ-144
 * @description ConnectController
 * @Date 2023/7/24 15
 */
@Slf4j
@Controller
public class ConnectController {

    @GetMapping("/wx")
    public void checkWx(@RequestParam String signature,@RequestParam String timestamp
            ,@RequestParam String nonce,@RequestParam String echostr,HttpServletResponse res) throws IOException {
        try {
            //校验
            List<String> list = new ArrayList<String>();
            list.add("fanlizhi");
            list.add(timestamp);
            list.add(nonce);
            //排序
            Collections.sort(list);
            //拼接字符串 ---》sha1加密
            StringBuffer buffer = new StringBuffer();
            for(String str:list){
                buffer.append(str);
            }
            //使用apache.commons.codec加密
            String sha1Str = DigestUtil.sha1Hex(buffer.toString());
            //对比
            boolean flag = sha1Str.equals(signature);
            if(signature.equals(sha1Str)){
                log.info("-------------恭喜接入成功！-------------");
                //获取输出
                PrintWriter out = res.getWriter();
                out.print(echostr);
                out.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 接收数据
     */
    @PostMapping("/wx")
    public void echoMessage(HttpServletRequest req, HttpServletResponse res) {
        //设置字符集
        try {
            req.setCharacterEncoding("UTF-8");
            res.setCharacterEncoding("UTF-8");
            //回送信息
            handleEchoMessage(req,res);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }
    /**
     * 自动回复消息
     *
     * 1.获取XML数据
     * 2.xml---》解析---》存放在map中---》xml数据
     * 3.xml数据解析转换成对象
     * 4.将对象中的属性 from---》to 调换位置 更改时间 内容
     * 5.将对象在转换为xml
     * @param req
     * @param res
     */
    private void handleEchoMessage(HttpServletRequest req, HttpServletResponse res) {
        Map<String,String> xmlMap = null;
        try {
            //xml---》解析---》存放在map中---》xml数据
            xmlMap = MessageUtils.toMap(req.getInputStream());
            //xml数据解析转换成对象
            Message message = MessageUtils.toMessage(xmlMap);
            //将对象中的属性 from---》to 调换位置 更改时间 内容
            String to = message.getToUserName();
            String from = message.getFromUserName();
            message.setFromUserName(to);
            message.setToUserName(from);

            message.setCreateTime(System.currentTimeMillis());
            String content = message.getContent();
            content = content==null?"":content.trim();

            //书写返回数据
            String reply = "";
            //获取消息类型
            String type = xmlMap.get("MsgType");
            //比较
            if(type.equals(MessageType.TEXT)){
                if(content.equals("1")||content.equalsIgnoreCase("sxt")){
                    reply = sxtText();
                }else if(content.equals("2")||content.equalsIgnoreCase("joke")){
                    reply = jokeText();
                }else if(content.equals("3")|| content.matches("[0-9]{6}")==true){
                    reply = postCode(content);
                }else if(content.equals("4")|| content.endsWith("#")){
                    reply = getpostCode(content);
                }else if(content.equals("?")|| content.equals("？")||content.equals("帮助")||content.equals("help")){
                    reply = mainMenu();
                }else{
                    //如果其他消息
                    reply = weather(content);
                }
            }else if(type.equals(MessageType.EVENT)){
                //获取事件类型
                String eventType = xmlMap.get("Event").toLowerCase();
                if(eventType.equals(MessageType.SUBSCRIBE)){//关注事件
                    reply = mainMenu();
                    message.setMsgType(MessageType.TEXT);
                }else if(eventType.equals(MessageType.UNSUBSCRIBE)){
                    System.out.println("有人退出了");
                }
            }
            //设置会送信息
            message.setContent(reply);
            //将message对象转换为xml格式
            String xmlStr = MessageUtils.toXml(message);
            System.out.println(xmlStr);
            //使用writer将信息发送出去
            PrintWriter out = res.getWriter();
            out.print(xmlStr);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 通过地区获取邮政编码
     * @param content
     * @return
     */
    private String getpostCode(String content) {
        content = content.replace("#", "");
        //获取邮政编码
        String postcode = PostCodeUtils.getPostCodeByDistrict(content);
        if(postcode==null || postcode.trim().equals("")){
            return "您的消息收到了，你发的信息为：---> "+content+",您输入的有误，正确方式为：\"安徽省,蚌埠市,五河县#\"或者\"上海市,辖区,徐汇区#\"。";
        }
        return postcode;
    }
    /**
     * 通过邮政编码获取地区
     * @param content
     * @return
     */
    private String postCode(String content) {
        //获取地区
        String district = PostCodeUtils.getPostCode(content);
        System.out.println(district);
        if(district==null || district.trim().equals("")){
            return "您的消息收到了，你发的信息为：---> "+content+",您输入的有误，请检查后重新输入。";
        }
        return district;
    }
    /**
     * 天气
     * @return
     */
    private String weather(String content) {
        content = content.replace("市", "");
        //获取天气字符串
        String weatherStr = WeatherUtils.getWeather(content);
        //处理null
        if(weatherStr==null || weatherStr.trim().equals("")){
            return other(content);
        }
        return weatherStr;
    }
    /**
     *
     * @param content
     * @return
     */
    private String other(String content) {
        return "您的消息收到了，你发的信息为：---> "+content;
    }
    /**
     * 主菜单
     * @return
     */
    private String mainMenu() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("欢迎您的关注，请按以下说明进行操作：\n");
        buffer.append("1、输入1 关注先锋铭品\n");
        buffer.append("2、输入\"joke\" 关注笑话大全：\n");
        buffer.append("3、输入邮政编码查看归属地区，如\"233300\"\n");
        buffer.append("4、输入地区查看邮政编码，如\"安徽省,蚌埠市,五河县#\"或者\"上海市,辖区,徐汇区#\"(省市县要以英文半角逗号分隔并以#号结尾)\n");
        buffer.append("5、输入？、?、help、帮助可获取最新更新内容");
        return buffer.toString();
    }
    /**
     * 笑话
     * @return
     */
    private String jokeText() {
        //获取地区
        String joke = JokeUtils.getJoke();
        System.out.println(joke);
        if(joke==null || joke.trim().equals("")){
            return "不好意思小猿打盹去了，请稍候再试。";
        }
        return joke;
    }
    /**
     * sxt
     * @return
     */
    private String sxtText() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("先锋铭品将给你不一样的体验，您值得拥有，欢迎您的加入！\n");
        return buffer.toString();
    }

}
